{% extends "base/base_layout.html" %}
{% load static %}
{% block sidebar_option %}
    sidebar-collapse
{% endblock %}
{% block extra_css %}
    <link rel="stylesheet" href="{% static "others/css/terminal.css" %}" type="text/css">
    <link rel="stylesheet" href="{% static "others/css/devices.min.css" %}" type="text/css">
    <link rel="stylesheet" href="{% static "codemirror/codemirror.css" %}" type="text/css">
    <link rel="stylesheet" href="{% static "codemirror/lint.css" %}" type="text/css">
    <link rel="stylesheet" href="{% static "others/css/spinner.css" %}">
    <style>
        textarea {
            width: 100%;
            height: {% if android_version < 5 %} 630px; {% else %} 170px; {% endif %}
            -moz-border-bottom-colors: none;
            -moz-border-left-colors: none;
            -moz-border-right-colors: none;
            -moz-border-top-colors: none;
            background: none repeat scroll 0 0 rgba(0, 0, 0, 0.07);
            border-color: -moz-use-text-color #FFFFFF #FFFFFF -moz-use-text-color;
            border-image: none;
            border-radius: 6px 6px 6px 6px;
            border-style: none solid solid none;
            border-width: medium 1px 1px medium;
            box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12) inset;
            color: #555555;
            font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
            font-size: 1em;
            line-height: 1.4em;
            padding: 5px 8px;
            transition: background-color 0.2s ease 0s;
        }

        textarea:focus {
            background: none repeat scroll 0 0 #FFFFFF;
            outline-width: 0;
        }

        .highlight {
            border: solid 2px #1e6dff;
        }

        .CodeMirror {
            height: 610px;
            font-size: 13px;
            border: 1px solid #eee;
        }

        .frida-pre {
            font-family: "courier new", courier, monospace;
            font-size: 11px;
        }
    </style>

{% endblock %}

{% block content %}

    <script src="{% static "adminlte/plugins/jquery.min.js" %}"></script>

    <div class="content-wrapper">
        <div class="content-header">
            <div class="container-fluid">
                <div class="row mb-2">
                    <div id="mobsf_header">
                        <h2><strong>动态扫描 </strong>- {{ package }}</h2>
                        <input type="hidden" id="screen_width" value="{{ screen_witdth }}">
                        <input type="hidden" id="screen_height" value="{{ screen_height }}">
                    </div>
                </div>
            </div>
        </div>
        <div class="container-fluid">


            <div class="row">
                <div class="col-md-12">
                    <div class="card card-default">
                        <!-- /.card-header -->
                        <div class="card-body">
                            <div id="but" align="center">
                                <a href="#" id="screen" class="btn btn-primary" role="button"><i
                                        class="fa fa-mobile-alt"></i> 现实</a>
                                <a href="#" id="rootca" class="btn btn-primary" role="button"><i
                                        class="fa fa-certificate"></i> 移除根 CA</a>
                                {% if android_version >= 5 %}
                                    <a href="#" id="proxy" class="btn btn-primary" role="button"><i
                                            class="fas fa-eye-slash"></i> Unset HTTP(S) Proxy</a>
                                    <a href="#" id="tls_test" class="btn btn-primary" role="button" data-toggle="modal"
                                       data-target="#tls_modal"><i class="fa fa-lock"></i> TLS/SSL Security Tester</a>
                                {% endif %}
                                <a href="#" id="expactt" class="btn btn-primary" role="button"><i
                                        class="fa fa-language"></i> 导出 Activity Tester</a>
                                <a href="#" id="actt" class="btn btn-primary" role="button"><i class="fa fa-rocket"></i>
                                    Activity Tester</a>
                                {% if android_version >= 5 %}
                                    <a href="#" id="deps" class="btn btn-primary" role="button"><i
                                            class="fas fa-running"></i> 获取依赖</a>
                                {% endif %}
                                <a href="#" id="ss" class="btn btn-primary" role="button"><i class="fa fa-camera"></i>
                                    截屏</a>
                                <a href="#" id="logstream" class="btn btn-primary"><i class="fa fa-water"></i>
                                   日志流</a>
                                <a href="../../live_api/?hash={{ hash }}&amp;package={{ package }}" id="apimon"
                                   target="_blank" class="btn btn-primary" style='display: none'><i
                                        class="fa fa-search"></i> Live API 监控</a>
                                <a href="#" id="stop" class="btn btn-info" role="button"><i class="fa fa-file-alt"></i>
                                    生成报告</a>
                            </div>
                        </div>
                        <!-- /.card-body -->
                    </div>
                    <!-- /.card -->
                </div>
                <!-- /.col -->


                <div class="col-md-4">
                    <div class="card card-default">
                        <!-- /.card-header -->
                        <div class="card-body">
                            <div align="center">
                                <div class="marvel-device htc-one">
                                    <div class="top-bar"></div>
                                    <div class="camera"></div>
                                    <div class="sensor"></div>
                                    <div class="speaker"></div>
                                    <div class="screen" id="container">
                                        <img width="320" height="580" src="../../download/screen/screen.png" id="my"
                                             onerror="$('#my').attr('src','/static/img/loading.jpg')"
                                             style="background-color:black;">
                                    </div>
                                </div>
                            </div>
                        </div>
                        <!-- /.card-body -->
                    </div>
                    <!-- /.card -->
                </div>
                <!-- /.col -->

                <div class="col-md-{% if android_version < 5 %}8{% else %}4{% endif %}">
                    <div class="card card-default">
                        <!-- /.card-header -->
                        <div class="card-body">

                            <div class="card card-primary card-outline card-outline-tabs">
                                <div class="card-header p-0 border-bottom-0">
                                    <ul class="nav nav-tabs" id="tabnav" role="tablist">
                                        <li class="nav-item">
                                            <a class="nav-link active" id="dm-tab" data-toggle="pill" href="#dm"
                                               role="tab" aria-controls="dm" aria-selected="true">动态分析</a>
                                        </li>
                                        <li class="nav-item">
                                            <a class="nav-link disabled" id="frida-tab" data-toggle="pill"
                                               href="#frida_logs" role="tab" aria-controls="frida"
                                               aria-selected="false">Frida Logs</a>
                                        </li>
                                        <li class="nav-item">
                                            <a class="nav-link" id="errors-tab" data-toggle="pill" href="#errors"
                                               role="tab" aria-controls="errors" aria-selected="false">错误</a>
                                        </li>
                                    </ul>
                                </div>
                                <div class="card-body">
                                    <div class="tab-content" id="tabs">
                                        <div class="tab-pane fade active show" id="dm" role="tabpanel"
                                             aria-labelledby="dm-tab">
                                            <textarea id="stat"></textarea>
                                            {% if android_version < 5 %}
                                                <!-- xposed only-->
                                                <br>
                                                <button id="run_app" class="btn btn-success"><i class="fas fa-play"></i>
                                                    启动app
                                                </button>
                                            {% endif %}
                                            <!--box-->
                                            <div id="frida_options" class="box box-primary">
                                                <div class="box-header with-border">
                                                    <h3 class="box-title">Frida Scripts</h3>
                                                </div>
                                                <!-- /.box-header -->
                                                <!-- form start -->
                                                <form role="form">
                                                    <div class="box-body">
                                                        <div class="form-group">
                                                            <hr/>
                                                            <h4> 默认 </h4>
                                                            <label>
                                                                <input name="default_hooks" type="checkbox"
                                                                       value="api_monitor" checked>
                                                                API监控
                                                            </label>
                                                            <label>
                                                                <input name="default_hooks" type="checkbox"
                                                                       value="ssl_pinning_bypass" checked>
                                                                SSL Pinning Bypass
                                                            </label>
                                                            <label>
                                                                <input name="default_hooks" type="checkbox"
                                                                       value="root_bypass" checked>
                                                                Root Detection Bypass
                                                            </label>
                                                            <label>
                                                                <input name="default_hooks" type="checkbox"
                                                                       value="debugger_check_bypass" checked>
                                                                Debugger Check Bypass
                                                            </label>
                                                        </div>
                                                        <hr/>
                                                        <div class="form-group">
                                                            <h4> Auxiliary </h4>
                                                            <label>
                                                                <input name="auxiliary" type="checkbox"
                                                                       value="enum_class" id="enum_class">
                                                                Enumerate Loaded Classes
                                                            </label>
                                                            <label>
                                                                <input name="auxiliary" type="checkbox"
                                                                       value="string_catch" id="string_catch">
                                                                Capture Strings
                                                            </label>
                                                            <label>
                                                                <input name="auxiliary" type="checkbox"
                                                                       value="string_compare" id="string_compare">
                                                                Capture String Comparisons
                                                            </label>
                                                            <br/>
                                                            <label>
                                                                <input onclick="aux_click(this)" name="auxiliary"
                                                                       type="checkbox" value="enum_methods"
                                                                       id="enum_methods">
                                                                枚举类方法
                                                            </label>
                                                            <input type="text" class="form-control" id="class_name"
                                                                   placeholder="java.io.File">

                                                            <label>
                                                                <input onclick="aux_click(this)" name="auxiliary"
                                                                       type="checkbox" value="search_class"
                                                                       id="search_class">
                                                                Search Class Pattern
                                                            </label>
                                                            <input type="text" class="form-control" id="class_search"
                                                                   placeholder="ssl\.Trust*">
                                                            <label>
                                                                <input onclick="aux_click(this)" name="auxiliary"
                                                                       type="checkbox" value="trace_class"
                                                                       id="trace_class">
                                                                Trace Class Methods
                                                            </label>
                                                            <input type="text" class="form-control" id="class_trace"
                                                                   placeholder="java.net.Socket,java.io.File,java.lang.String">
                                                        </div>


                                                    </div>
                                                    <!-- /.box-body -->

                                                    <div class="box-footer">

                                                        <button id="frida_spawn" type="submit" class="btn btn-success">
                                                            <i class="fas fa-play"></i> 启动仪器
                                                        </button>
                                                        <button id="fd_log" type="button" class="btn btn-primary"
                                                                disabled><i class="fas fa-file-medical-alt"></i> Frida
                                                            Live Logs
                                                        </button>
                                                    </div>
                                                </form>
                                            </div>

                                            <!--tab end-->

                                        </div>

                                        <div class="tab-pane fade" id="frida_logs" role="tabpanel"
                                             aria-labelledby="frida-tab">
                                            <h4 class="page-header"><strong>Frida Logs </strong>- {{ package }}</h4>
                                            <div id="messages"></br>每三秒刷新一次.</div>
                                            <pre class="frida-pre" id="logs"></pre>
                                        </div>
                                        <!-- frida logs -->
                                        <div class="tab-pane fade" id="errors" role="tabpanel"
                                             aria-labelledby="errors-tab">


                                            <iframe sandbox frameborder="0" width="100%" height="650px"
                                                    id="er"></iframe>


                                        </div>
                                    </div>
                                </div>
                                <!-- /.card -->
                            </div>


                        </div>
                        <!-- /.card-body -->
                    </div>
                    <!-- /.card -->
                </div>
                <!-- /.col -->

                <div class="col-md-4" id="codeedit">
                    <div class="card card-default">
                        <div class="card-header">
                            <h3 class="card-title"><i class="fa fa-code"></i> Frida Code 编辑 </h3>
                            <!-- /.card-tools -->
                        </div>
                        <!-- /.card-header -->
                        <div class="card-body">
                            <div class="row">
                                <div class="col-12">
<textarea id="code-js" rows="100">
Java.perform(function() {
  // Use send() for logging
});
</textarea>
                                </div>
                                <div class="col-12">
                                    <br/>
                                    <div class="form-group">
                                        <span class="box-title">可用脚本 (Use CTRL to choose multiple)  </span>
                                        <button id="loadscript" type="submit" class="btn btn-primary btn-sm">
                                            加载
                                        </button>
                                    </div>
                                    <div class="form-group">
                                        <select id="fd_scs" multiple="" class="form-control">
                                        </select>
                                    </div>
                                </div>
                            </div>
                            <!-- end row-->

                        </div>
                        <!-- /.card-body -->
                    </div>
                    <!-- /.card -->
                </div>
                <!-- /.col -->

                <div class="col-md-12">
                    <div class="card card-default">
                        <!-- /.card-header -->
                        <div class="card-body">

                            <div id="shell">
                                <output></output>
                                <div id="input-line" class="input-line">
                                    <div class="prompt"></div>
                                    <div><input class="cmdline" autofocus/></div>
                                </div>
                            </div>

                        </div>
                        <!-- /.card-body -->
                    </div>
                    <!-- /.card -->
                </div>
                <!-- /.col -->

            </div>

        </div>
    </div>
    </div>
    </div>
    </div>
    <!-- Modal -->
    <div class="modal" id="tls_modal" tabindex="-1" role="dialog">
        <div class="modal-dialog modal-xl">
            <div class="modal-content">
                <div class="modal-header">
                    <h4 class="modal-title">执行 TLS/SSL Security 测试 - {{ package }}</h4>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">×</span>
                    </button>
                </div>
                <div class="modal-body">
                    <form role="form">
                        <div class="form-group">
                            <p>TLS/SSL 安全测试可帮助您评估应用程序网络的安全性
                                 连接。 这些测试仅适用于执行网络
                                 HTTP 协议上的连接。 我们针对
                                 应用。<br>
                            </p>
                            <p>
                                <strong>TLS Misconfiguration Test </strong> - Enable HTTPS MITM Proxy, Remove Root CA,
                                Run the App for 25 seconds.<br>
                                <code>This test will uncover insecure configurations that allow HTTPS connections
                                    bypassing certificate errors or SSL/TLS errors in WebViews. This is equivalent to
                                    not having TLS.</code><br>
                            </p>
                            <p>
                                <strong>TLS Pinning/Certificate Transparency Test </strong> - Enable HTTPS MITM Proxy,
                                Install Root CA, Run the App for 25 seconds.<br>
                                <code>This test will evaluate the application's TLS/SSL hardening controls and will
                                    check if the application implement certificate or public key pinning and or
                                    certificate transparency.</code><br>
                            <p>
                                <strong>TLS Pinning/Certificate Transparency Bypass Test </strong> - Enable HTTPS MITM
                                Proxy, Install Root CA, Bypass Certificate/Public Key Pinning or Certificate
                                Transparency.<br>
                                <code>This test tries to bypass certificate or public key pinning and or certificate
                                    transparency controls in your application. MobSF can bypass most of the generic
                                    implementations.</code><br>
                            </p>
                            <p><strong>NOTE: </strong><i>For Better results, while the application is running, navigate
                                through different business logic flows that will trigger network connections over HTTP
                                protocol. Make sure that no other applications are running during the test.</i></p>
                        </div>
                        <div class="form-group">
                            <label>测试进度</label>
                            <textarea id="tls_text" class="form-control" rows="10" placeholder=""
                                      disabled=""></textarea>
                        </div>
                        <div class="form-group">
                            <table class="table table-bordered table-hover table-striped">
                                <thead>
                                <tr>
                                    <th>测试</th>
                                    <th>结果</th>
                                </tr>
                                </thead>
                                <tbody>
                                <tr>
                                    <td>TLS Misconfiguration Test</td>
                                    <td id="tls_1">-</td>
                                </tr>
                                <tr>
                                    <td>TLS Pinning/Certificate Transparency Test</td>
                                    <td id="tls_2">-</td>
                                </tr>
                                <tr>
                                    <td>TLS Pinning/Certificate Transparency Bypass Test</td>
                                    <td id="tls_3">-</td>
                                </tr>
                                <tr>
                                    <td>Cleartext Traffic Test</td>
                                    <td id="tls_4">-</td>
                                </tr>
                                </tbody>
                            </table>
                        </div>

                    </form>
                </div>
                <div class="modal-footer">
                    <button id="run_tls_tests" type="button" class="btn btn-primary"><i class="fas fa-bolt"></i> Run
                        TLS/SSL 测试
                    </button>
                </div>
            </div>

            <!--Loader-->
            <div class="hidden loading">
                <div class='uil-ring-css' style='transform:scale(0.79);'>
                    <div></div>
                </div>
            </div>


            <!-- /.modal-content -->
        </div>
        <!-- /.modal-dialog -->
    </div>
    <!-- End Modal -->

{% endblock %}
{% block extra_scripts %}
    <script src="{% static "codemirror/codemirror.js" %}"></script>
    <script src="{% static "codemirror/javascript.js" %}"></script>
    <script src="{% static "codemirror/jshint.js" %}"></script>
    <script src="{% static "codemirror/lint.js" %}"></script>
    <script src="{% static "codemirror/javascript-lint.js" %}"></script>
    <script>
        // Loading Spinner
        function dynamic_loader() {
            var loadingOverlay = document.querySelector('.loading');
            loadingOverlay.classList.remove('hidden');
        }

        function stop_loader() {
            var loadingOverlay = document.querySelector('.loading');
            loadingOverlay.classList.add('hidden');
        }

        // Frida Auxiliary actions

        function aux_click(cb) {
            if (cb.checked && cb.value === 'search_class')
                $('#cls_search').addClass('highlight')
            else if (!cb.checked && cb.value === 'search_class')
                $('#cls_search').removeClass('highlight')
            else if (cb.checked && cb.value === 'enum_methods')
                $('#cls_name').addClass('highlight')
            else if (!cb.checked && cb.value === 'enum_methods')
                $('#cls_name').removeClass('highlight')
            else if (cb.checked && cb.value === 'trace_class')
                $('#cls_trace').addClass('highlight')
            else if (!cb.checked && cb.value === 'trace_class')
                $('#cls_trace').removeClass('highlight')
        }


        //For All Ajax
        function action(url, data, on_success) {
            //Add CSRF
            data.csrfmiddlewaretoken = '{{ csrf_token }}';
            $.ajax({
                url: url,
                type: "POST",
                dataType: "json",
                data: data,
                success: function (json) {
                    on_success(json)
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    document.getElementById("er").srcdoc = xhr.responseText;
                }
            });
        }

        // Frida load other scripts
        function load_frida_others() {
            $.get(document.location.origin + '/list_frida_scripts/', function (json, status) {
                if (json.status == 'ok') {
                    json.files.forEach(function (script) {
                        $('#fd_scs').append('<option value=' + escape(script) + '>' + escape(script) + '</option>');
                    });
                }
            });
        }

        // Code Editor
        var editor = CodeMirror.fromTextArea(document.getElementById("code-js"), {
            lineNumbers: true,
            mode: "javascript",
            gutters: ["CodeMirror-lint-markers"],
            lint: true,
            lineWrapping: true,
            onLoad: restore(),
        });

        //Restore Code
        function restore() {
            var custom_code = window.sessionStorage.getItem("code");
            if (custom_code !== null) {
                setTimeout(function () {
                    editor.getDoc().setValue(custom_code);
                }, 2000);
            }
        }

        // Terminal
        var util = util || {};
        util.toArray = function (list) {
            return Array.prototype.slice.call(list || [], 0);
        };

        var Terminal = Terminal || function (cmdLineContainer, outputContainer) {
            window.URL = window.URL || window.webkitURL;
            window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;

            var cmdLine_ = document.querySelector(cmdLineContainer);
            var output_ = document.querySelector(outputContainer);

            const CMDS_ = [
                'activities', 'exported_activities', 'services', 'receivers', 'providers', 'libraries',
                'clear', 'date', 'echo', 'help', 'shell', 'pull', 'push',
                'devices', 'forward', 'start-server', 'kill-server', 'wait-for-device',
                'connect', 'reconnect', 'disconnect', 'usb', 'install', 'uninstall',
                'logcat', 'root', 'sideload', 'tcpip', 'unroot',
                'reboot', 'remount', 'get-devpath', 'get-serialno', 'get-state',
                'keygen', 'enable-verity', 'disable-verity', 'jdwp', 'bugreport',
                'backup', 'restore', 'install-multi-package', 'install-multiple',
                'sync', 'reverse', 'ppp', 'version',

            ];

            var history_ = [];
            var histpos_ = 0;
            var histtemp_ = 0;
            var intro = '<h3 style="letter-spacing: 2px">Shell Access</h3><p>' + new Date() + '</p><p>Enter "help" for more information.</p>';
            var shell = document.getElementById('shell');
            shell.addEventListener('click', function (e) {
                cmdLine_.focus();
            }, false);

            cmdLine_.addEventListener('click', inputTextClick_, false);
            cmdLine_.addEventListener('keydown', historyHandler_, false);
            cmdLine_.addEventListener('keydown', processNewCommand_, false);

            function inputTextClick_(e) {
                this.value = this.value;
            }

            function historyHandler_(e) {
                if (history_.length) {
                    if (e.keyCode == 38 || e.keyCode == 40) {
                        if (history_[histpos_]) {
                            history_[histpos_] = this.value;
                        } else {
                            histtemp_ = this.value;
                        }
                    }

                    if (e.keyCode == 38) { // up
                        histpos_--;
                        if (histpos_ < 0) {
                            histpos_ = 0;
                        }
                    } else if (e.keyCode == 40) { // down
                        histpos_++;
                        if (histpos_ > history_.length) {
                            histpos_ = history_.length;
                        }
                    }

                    if (e.keyCode == 38 || e.keyCode == 40) {
                        this.value = history_[histpos_] ? history_[histpos_] : histtemp_;
                        this.value = this.value; // Sets cursor to end of input.
                    }
                }
            }

            function escape(data) {
                var encodedStr = data.replace(/[\u00A0-\u9999<>\&]/gim, function (i) {
                    return '&#' + i.charCodeAt(0) + ';';
                });
                return encodedStr;
            }

            function output(html, escape_ = false, pre = false, error = false) {
                if (escape_)
                    html = escape(html);
                if (pre)
                    output_.insertAdjacentHTML('beforeEnd', '<pre class="clean-text">' + html + '</pre>');
                else if (error)
                    output_.insertAdjacentHTML('beforeEnd', '<pre>' + html + '</pre>');
                else
                    output_.insertAdjacentHTML('beforeEnd', '<p>' + html + '</p>');
            }

            // Cross-browser impl to get document's height.
            function getDocHeight_() {
                var d = document;
                return Math.max(
                    Math.max(d.body.scrollHeight, d.documentElement.scrollHeight),
                    Math.max(d.body.offsetHeight, d.documentElement.offsetHeight),
                    Math.max(d.body.clientHeight, d.documentElement.clientHeight)
                );
            }

            function get_comp(comp) {
                action(document.location.origin + '/get_component/', {
                    component: comp,
                    hash: '{{ hash }}'
                }, function (json) {
                    if (json.status === "ok")
                        output(json.message, true, true);
                    else
                        output(json.message, true, true, true);
                });
            }

            function execute_adb(exec_cmd) {
                action(document.location.origin + '/execute_adb/', {cmd: exec_cmd}, function (json) {
                    if (json.status === "ok")
                        output(json.message, true, true);
                });
            }

            function processNewCommand_(e) {

                if (e.keyCode == 9) { // tab
                    e.preventDefault();
                    // Implement tab suggest.
                } else if (e.keyCode == 13) { // enter
                    // Save shell history.
                    if (this.value) {
                        history_[history_.length] = this.value;
                        histpos_ = history_.length;
                    }

                    // Duplicate current input and append to output section.
                    var line = this.parentNode.parentNode.cloneNode(true);
                    line.removeAttribute('id')
                    line.classList.add('line');
                    var input = line.querySelector('input.cmdline');
                    input.autofocus = false;
                    input.readOnly = true;
                    output_.appendChild(line);

                    if (this.value && this.value.trim()) {
                        var args = this.value.split(' ').filter(function (val, i) {
                            return val;
                        });
                        var cmd = args[0].toLowerCase();
                        var exec_cmd = args.join(' ');
                        args = args.splice(1); // Remove cmd from arg list.
                    }

                    switch (cmd) {
                        case 'clear':
                            output_.innerHTML = '';
                            this.value = '';
                            output(intro);
                            return;
                        case 'date':
                            output(new Date());
                            break;
                        case 'echo':
                            output(exec_cmd, true);
                            break;
                        case 'activities':
                            get_comp('activities')
                            break;
                        case 'exported_activities':
                            get_comp('exported_activities')
                            break;
                        case 'services':
                            get_comp('services')
                            break;
                        case 'receivers':
                            get_comp('receivers')
                            break;
                        case 'providers':
                            get_comp('providers')
                            break;
                        case 'libraries':
                            get_comp('libraries')
                            break;
                        case 'help':
                            output('<div class="ls-files">' + CMDS_.join('<br>') + '</div>');
                            break;
                        default:
                            if (cmd === 'shell' && args.length === 0)
                                output("Incomplete command. expecting shell &lt;cmd&gt;");
                            else if (exec_cmd.length > 0)
                                execute_adb(exec_cmd)
                    }
                    ;
                    window.scrollTo(0, getDocHeight_());
                    this.value = ''; // Clear/setup line for next input.
                }
            }

            return {
                init: function () {
                    output(intro);
                },
                output: output
            }
        };

        $(document).ready(function () {

//Terminal
            $('.prompt').html('[root@android] # ');
            var term = new Terminal('#input-line .cmdline', '#shell output');
            term.init();

// Start up
            {% if android_version < 5 %}
                $('#frida_options').hide()
                $('#codeedit').hide()
            {% else %}
                load_frida_others();
            {% endif %}


// Disable Activity Tester and Exported Activity Tester for on Device only apps
            var loc = location.href;
            if (loc.includes('&install=0')) {
                $('#expactt').hide();
                $('#actt').hide();
            }


//Print Status
            function print_status(message) {
                $('#stat').append(message + '\n');
                $('#stat').scrollTop($('#stat')[0].scrollHeight);
            }

//Print TLS/SSL test progress inside modal
            function print_tls_progress(message) {
                $('#tls_text').append(message + '\n');
                $('#tls_text').scrollTop($('#tls_text')[0].scrollHeight);
            }

            print_status("Setting up MobSF Dynamic Analysis environment...");
            print_status("Running HTTP(S) interception proxy.");
            print_status("Invoking MobSF agents.");
            print_status("Environment is ready for Dynamic Analysis.");
            print_status("Start Instrumentation or Run the application and navigate through the different flows or business logic manually.");

// Frida Logs Tab

            function get_logs() {
                $.ajax({
                    url: '/frida_logs/?hash={{ hash }}&stream=1',
                    type: "GET",
                    dataType: "json",
                    success: function (json) {
                        $('#logs').text(json.data);
                    },
                    error: function (xhr, ajaxOptions, thrownError) {
                        console.log(xhr.responseText);
                    }
                });
            }

            get_logs();
            setInterval(function () {
                get_logs();
            }, 3000);

// Touch Events
            var touch = "off";

            $('#my').click(function (e) {
                if (touch === "on") {
                    var res = [$('#screen_width').val(), $('#screen_height').val()];
                    var width = res[0];
                    var height = res[1];
                    if (width.length > 0 && height.length > 0) {
                        width = parseInt(width);
                        height = parseInt(height);
                        var offset = $(this).offset();
                        var x = e.pageX - offset.left;
                        var y = e.pageY - offset.top;
                        x = x * (width / 320);
                        y = y * (height / 580);
                        console.log('X Axis: ' + x + " Y Axis: " + y);
                        action(document.location.origin + '/touch_events/', {x: x, y: y}, function (json) {
                            if (json.status === 'ok')
                                console.log('Clicked!');
                            else
                                console.log(json.message)
                        });
                    }
                }
            });

// View Screen
            var screenfunc;
            $("#screen").click(function () {
                var stext = $("#screen").text();
                if (stext.includes("Show Screen")) {
                    $("#screen").html("<i class='fa fa-mobile'></i> Stop Screen");
                    print_status('Screen streaming started.')
                    touch = "on";
                    screenfunc = setInterval(function () {
                        // Capture Screen
                        action(document.location.origin + '/screen_cast/', {}, function (json) {
                            if (json.status == 'ok')
                                $('#my').attr('src', document.location.origin + '/download/screen/screen.png?' + new Date().getTime());
                            else
                                console.log(json.message)
                        });
                    }, 3000);
                } else {
                    $("#screen").html("<i class='fa fa-mobile-alt'></i> Show Screen");
                    print_status("Screen streaming stopped.");
                    $('#my').attr('src', '/static/img/loading.jpg');
                    clearInterval(screenfunc);
                    touch = "off";
                }
                return false;
            });

//Screenshot
            $("#ss").click(function () {
                print_status("Taking a screenshot.");
                action(document.location.origin + '/screenshot/', {hash: '{{ hash }}'}, function (json) {
                    if (json.status === "ok") {
                        print_status("Screenshot taken!");
                    } else {
                        print_status("Failed to take screenshot!");
                        print_status(json.message);
                    }
                });
                return false;
            });

//MobSF CA

            $("#rootca").click(function () {
                var stext = $("#rootca").text();
                var act;
                if (stext.includes("Remove Root CA")) {
                    $("#rootca").html("<i class='fa fa-certificate'></i> Install Root CA");
                    act = "remove";
                } else {
                    $("#rootca").html("<i class='fa fa-certificate'></i> Remove Root CA");
                    act = "install";
                }
                action(document.location.origin + '/mobsf_ca/', {action: act}, function (json) {
                    if (json.message === "installed")
                        print_status("MobSF Root CA installed successfully.");
                    else if (json.message === "removed")
                        print_status("MobSF Root CA removed successfully.");
                    else
                        print_status(json.message);
                });
                return false;
            });


//MobSF Global Proxy

            $("#proxy").click(function () {
                var stext = $("#proxy").text();
                var act;
                if (stext.includes("Unset HTTP(S) Proxy")) {
                    $("#proxy").html("<i class='fas fa-eye'></i> Set HTTP(S) Proxy");
                    act = "unset";
                } else {
                    $("#proxy").html("<i class='fas fa-eye-slash'></i> Unset HTTP(S) Proxy");
                    act = "set";
                }
                action(document.location.origin + '/global_proxy/', {action: act}, function (json) {
                    if (json.message === "set")
                        print_status("MobSF Global HTTP(S) interception proxy is applied.");
                    else if (json.message === "unset")
                        print_status("MobSF Global HTTP(S) interception proxy is removed.");
                    else
                        print_status(json.message);
                });
                return false;
            });

            function activity_tester(test) {
                action(document.location.origin + '/activity_tester/', {
                    hash: '{{ hash }}',
                    'test': test
                }, function (json) {
                    if (json.status === "ok")
                        if (test === 'exported')
                            print_status("Exported Activity testing completed.");
                        else
                            print_status("Activity testing completed.");
                    else
                        print_status(json.message);
                });
            }

//Start ExportedActivity Tester
            $("#expactt").click(function () {
                print_status("Starting Exported Activity tester...")
                activity_tester('exported')
                return false;
            });

//Start Activity Tester
            $("#actt").click(function () {
                print_status("Starting Activity tester...")
                activity_tester('all_activities')
                return false;
            });

//SSL/TLS Tester
            $('#run_tls_tests').click(function () {
                const msg = "TLS/SSL tests will take 75 seconds to complete. While the application is running, please navigate through different activity flows/business logic.";
                $('#tls_1').text('-');
                $('#tls_2').text('-');
                $('#tls_3').text('-');
                $('#tls_4').text('-');
                print_status("Running TLS/SSL Security Tester");
                print_tls_progress("Running TLS Misconfiguration test.")
                print_tls_progress("Running TLS Pinning/Certificate Transparency test.")
                print_tls_progress("Running TLS Pinning/Certificate Transparency Bypass test.")
                print_tls_progress(msg)
                dynamic_loader();
                action(document.location.origin + '/tls_tests/', {hash: '{{ hash }}'}, function (json) {
                    if (json.status === "ok") {
                        stop_loader();
                        // print_tls_progress(JSON.stringify(json.tls_tests))
                        if (json.tls_tests.tls_misconfigured === true)
                            $('#tls_1').text('❌')
                        else
                            $('#tls_1').text('✅')
                        if (json.tls_tests.no_tls_pin_or_transparency === true)
                            $('#tls_2').text('❌')
                        else
                            $('#tls_2').text('✅')
                        if (json.tls_tests.pin_or_transparency_bypassed === true)
                            $('#tls_3').text('❌')
                        else
                            $('#tls_3').text('✅')
                        if (json.tls_tests.has_cleartext === true)
                            $('#tls_4').text('❌')
                        else
                            $('#tls_4').text('✅')
                        const ok = "TLS/SSL Security tests completed.";
                        print_status(ok)
                        print_tls_progress(ok)
                    } else {
                        stop_loader();
                        print_status("TLS/SSL Security tests failed.")
                        print_tls_progress("TLS/SSL Security tests failed.")
                        print_tls_progress("[ERROR]")
                        print_tls_progress(json.message)
                    }
                });
                return false;
            });

// Run APK for Xposed
            $("#run_app").click(function () {
                print_status("Launching App");
                action(document.location.origin + '/run_apk/', {hash: '{{ hash }}'}, function (json) {
                    if (json.status === "ok") {
                        print_status("Application launched.");
                    } else {
                        print_status("Failed to launch the application.");
                    }
                });
                return false;
            });

// Logcat Stream
            $("#logstream").click(function () {
                print_status("Logcat Steaming started.");
                setTimeout(function () {
                    window.open(document.location.origin + '/logcat/?package={{ package }}', '_blank');
                }, 500);
                return false;
            });
// Frida logs
            $("#fd_log").click(function () {
                $('#tabnav a[href="#frida_logs"]').tab('show');
                // print_status("Streaming Frida logs");
                // setTimeout(function(){ window.open(document.location.origin + '/frida_logs/?hash={{ hash }}&package={{ package }}', '_blank');}, 100);
                document.body.scrollTop = document.documentElement.scrollTop = 0;
                return false;
            });


// Load Frida Scripts
            $("#loadscript").click(function () {
                var scripts = $('#fd_scs').val();
                action(document.location.origin + '/get_script/', {scripts: scripts}, function (json) {
                    if (json.status === "ok") {
                        editor.getDoc().setValue(json.content);
                    }
                });
                return false;
            });


// Frida Spawn
            $("#frida_spawn").click(function () {
                print_status("Instrumenting the application with Frida.");
                // Save Frida Code to Session Storage
                var code = editor.getDoc().getValue();
                window.sessionStorage.setItem('code', code);
                $('#fd_log').removeAttr('disabled');
                $('#frida-tab').removeClass('disabled');
                var default_hooks = [];
                $.each($("input[name='default_hooks']:checked"), function () {
                    default_hooks.push($(this).val());
                });
                if (default_hooks.includes("api_monitor"))
                    $('#apimon').show();
                else
                    $('#apimon').hide();

                var auxiliary_hooks = [];
                $.each($("input[name='auxiliary']:checked"), function () {
                    auxiliary_hooks.push($(this).val());
                });

                action(document.location.origin + '/frida_instrument/', {
                    hash: '{{ hash }}',
                    default_hooks: default_hooks.join(","),
                    auxiliary_hooks: auxiliary_hooks.join(","),
                    class_name: $('#class_name').val(),
                    class_search: $('#class_search').val(),
                    class_trace: $('#class_trace').val(),
                    frida_code: editor.getDoc().getValue(),
                }, function (json) {
                    if (json.status === "ok")
                        print_status("Frida instrumentation successful.");
                    else
                        print_status(json.message);
                });
                return false;
            });

//Frida Get Runtime Dependencies
            $("#deps").click(function () {
                print_status("Getting application runtime dependencies.");
                action(document.location.origin + '/get_dependencies/', {hash: '{{ hash }}'}, function (json) {
                    if (json.status === "ok") {
                        $('#fd_log').removeAttr('disabled');
                        $('#frida-tab').removeClass('disabled');
                        print_status("Dependencies collected!");
                    } else {
                        print_status(json.message);
                    }
                });
                return false;
            });

//Dump App data
            function dump() {
                action(document.location.origin + '/download_data/', {hash: '{{ hash }}'}, function (json) {
                    if (json.status === "ok") {
                        print_status("Application data dumped!");
                        print_status("Generating Report...Please Wait!");
                        //Call reporting
                        window.location = document.location.origin + "/dynamic_report/{{ hash }}";
                    } else {
                        print_status(json.message);
                    }
                });
            }

//Finish & Generate Report
            $("#stop").one("click", function () {
                print_status("Collecting data...");
                //Stop Screen Casting if it's running
                var stext = $("#screen").text();
                if (stext.includes("Stop Screen"))
                    $("#screen").click();
                action(document.location.origin + '/collect_logs/', {hash: '{{ hash }}'}, function (json) {
                    if (json.status === "ok") {
                        $('#stop').addClass("btn btn-success");
                        $('#stop').text("Please Wait...");
                        print_status("Downloading logs.");
                        print_status("Stopping Application.");
                    } else {
                        print_status('Failed to collect data.')
                        print_status(json.message)
                    }
                    dump();
                });
                return false;
            });

//end document.ready
        });
    </script>
{% endblock %}
